// CHECK: [[# FILENUM:]] "{{.*}}/HelloWorld.c"

// CHECK: pragma !1 icall_hint "bar, 0, 3, 3, 5"
// CHECK: pragma !2 icall_hint "bar"
// CHECK: pragma !3 icall_hint "bar, 0, 3"
struct A {
  int (*func)(int, int, void*);
};
struct B {
  int b;
};

typedef int (*nhp_ext_func)(int a);
  nhp_ext_func g_nhp[10] = {
};

__attribute__ ((noinline))
int bar(int a, int b, void *c) {
  if (c == 0) {
    return 0;
  }
  return a + b + *(int*)c;
}

int foo(int a, struct A *fa, void *param, int b) {
  if (a < 0) {
    return 0;
  }
  struct A *fb;
  struct A *fc;
  struct B stB = {b = 1};
  // CHECK: LOC 2 35 3
  // CHECK:    dread ptr %param) { dassign %retVar_5 0 } !1
  #pragma icall_hint(bar, 0, 3, 3, 5)
  fc->func(stB.b, 5, param);
  // CHECK: LOC 2 38 3
  // CHECK:    dread ptr %param) { dassign %retVar_6 0 }
  fc->func(1, 5, param);
  // CHECK: LOC 2 44 15
  // CHECK:    dread ptr %param) { dassign %retVar_8 0 }
  // CHECK: LOC 2 44 3
  // CHECK:     dread ptr %param) { dassign %retVar_7 0 }
  #pragma icall_hint(bar, 1, 2)
  fa->func(2, fb->func(1, 1, param), param);
  // CHECK: LOC 2 48 13
  // CHECK:     constval i32 2) { dassign %retVar_9 0 } !2
  _Pragma("icall_hint (bar)")
  int ret = g_nhp[1](2);
  // CHECK: LOC 2 52 10
  // CHECK:     dread ptr %param) { dassign %retVar_10 0 } !3
  _Pragma("icall_hint (bar, 0, 3)")
  return fa->func(2, 5, param);
}

int call(struct A *fa) {
  int a = 9;
  return foo(3, fa, &a, 4);
}

int main() {
  return 0;
}